﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "GcmpCommonEdit.h"
#include "IPickEventHandler.h"

namespace gcmp
{
    class IActionModifyBehavior;
    class IPickFilter;
    class IPickTarget;
    class IPickEvent;
    class IActionModifyDoubleClickEventHandler;


    /// \brief 默认修改Action设置，用于创建默认修改Action参数。
    class GCMP_COMMON_EDIT_EXPORT ActionModifyInput
    {
        CANNOT_COPY_OR_ASSIGN(ActionModifyInput)
    public:
        /// \brief 创建默认修改Action配置。
        /// 
        /// \param isMoveAllowed         是否允许移动对象
        /// \param isPickingHighlightAllowed  是否允许仅在高亮时显示的对象被拾取。
        /// \param isSelectByFaceInteriorEnabled  是否允许按面被选择。
        ///   每个图元常常会有一些辅助的显示节点，比如圆的圆心，墙的中心线等，只有在需要高亮的时候才显示。
        ActionModifyInput(
            bool isMoveAllowed = true,
            bool isPickingHighlightOnlyGraphicsNodeAllowed = false,
            bool isSelectByFaceInteriorEnabled = true);

        /// \brief 析构函数
        /// \return 
        ~ActionModifyInput(){}

        /// \brief 是否允许移动对象
        /// \return 如果允许，返回true；否则返回false
        bool IsMoveAllowed();

        /// \brief 是否允许仅在高亮时显示的对象被拾取。
        ///   每个图元常常会有一些辅助的显示节点，比如圆的圆心，墙的中心线等，只有在需要高亮的时候才显示。
        /// \return 如果允许，返回true；否则，返回false。
        bool IsPickingHighlightOnlyGraphicsNodeAllowed();

        /// \brief 能否通过面内部被拾取
        /// \return 如果能够，返回true；否则，返回false，仅能靠面的边来拾取。
        bool IsSelectByFaceInteriorEnabled() const;

        /// \brief 获取拾取目标。
        /// \return 返回拾取目标接口OnwerPtr。
        OwnerPtr<IPickTarget> GetPickTarget();

        /// \brief 获取拾取过滤器。
        /// \return 返回拾取过滤器接口的OnwerPtr。
        OwnerPtr<IPickFilter> GetPickFilter();

        /// \brief 获取进程捕捉的过滤器
        /// \return 返回进程捕捉的过滤器接口的OnwerPtr。
        OwnerPtr<IPickFilter> GetPickFilterForLocalSnap();

        /// \brief 获取远程捕捉的过滤器接口
        /// \return 返回远程捕捉的过滤器接口OnwerPtr。
        OwnerPtr<IPickFilter> GetPickFilterForRemoteSnap();

        /// \brief 获取拾取后处理事件。
        /// \return 返回拾取后处理事件的OnwerPtr。
        OwnerPtr<IPickEvent> GetPickPostProcessEvent();

        /// \brief 获取拾取后处理事件的处理器。
        /// \return 返回拾取后处理事件的处理器数组。
        std::vector<OwnerPtr<IPickEventHandler>> GetPickPostProcessEventHandler();

        /// \brief 获取拾取像素容差。
        /// \return 返回拾取像素容差。
        int GetPickPixelTolerance() const;

        /// \brief 获取双击事件处理器。
        /// \return 返回双击事件处理器的OnwerPtr。
        OwnerPtr<IActionModifyDoubleClickEventHandler> GetActionModifyDoubleClickEventHandler();

        /// \brief 获取ActionModifyBehavior
        /// \return 返回ActionModifyBehavior接口OnwerPtr。
        OwnerPtr<IActionModifyBehavior> GetActionModifyBehavior();

        /// \brief 设置是否允许移动对象
        /// \param bAllowed 是否允许移动对象
        /// \return void
        void SetIsMoveAllowed(bool bAllowed);

        /// \brief 设置是否允许仅仅高亮显示的对象被拾取
        /// \param bAllowed 是否允许拾取
        /// \return void
        void SetIsPickingHighlightOnlyGraphicsNodeAllowed(bool bAllowed);

        /// \brief 设置拾取面的方式，能否通过面内部被拾取，如果否，则仅能靠面的边来拾取
        /// \param enable 能否通过面内部被拾取，true表示能够，false表示不能
        /// \return 设置成功返回true，失败返回false
        bool SetSelectByFaceInteriorEnabled(bool enable);

        /// \brief 设置拾取目标
        /// \param opPickTarget 新的拾取目标
        /// \return void
        void SetPickTarget(OwnerPtr<IPickTarget> opPickTarget);

        /// \brief 设置拾取过滤器
        /// \param opPickFilter 新的拾取过滤器
        /// \return void
        void SetPickFilter(OwnerPtr<IPickFilter> opPickFilter);

        /// \brief 设置进程捕捉过滤器 
        /// \param opPickFilterForLocalSnap 新的进程捕捉过滤器
        /// \return void
        void SetPickFilterForLocalSnap(OwnerPtr<IPickFilter> opPickFilterForLocalSnap);

        /// \brief 设置远程捕捉过滤器
        /// \param opPickFilterForRemoteSnap 新的远程捕捉过滤器
        /// \return void
        void SetPickFilterForRemoteSnap(OwnerPtr<IPickFilter> opPickFilterForRemoteSnap);

        /// \brief 设置拾取后处理事件
        /// \param opPickPostProcessEvent 新的拾取后处理事件
        /// \return void
        void SetPickPostProcessEvent(OwnerPtr<IPickEvent> opPickPostProcessEvent);

        /// \brief 增加拾取后处理事件处理器
        /// \param opPickPostProcessEventHandler 新的拾取后处理事件处理器
        /// \return void
        void AddPickPostProcessEventHandler(OwnerPtr<IPickEventHandler> opPickPostProcessEventHandler);

        /// \brief 设置拾取像素容差
        /// \param pixelTolerance 所需设置的容差值，当值为负时，平台会将拾取像素容差设置为5
        /// \return void
        void SetPickPixelTolerance(int pixelTolerance);

        /// \brief 设置ActionModifyBehavior
        /// \param opActionModifyBehavior 设置新的ActionModifyBehavior接口
        /// \return void
        void SetActionModifyBehavior(OwnerPtr<IActionModifyBehavior> opActionModifyBehavior);

    private:
        OwnerPtr<IPickTarget>  m_opPickTarget;
        OwnerPtr<IPickFilter>  m_opPickFilter;
        OwnerPtr<IPickFilter>  m_opFilterForLocalSnap;
        OwnerPtr<IPickFilter>  m_opFilterForRemoteSnap;
        OwnerPtr<IPickEvent>   m_opPickPostProcessEvent;
        std::vector<OwnerPtr<IPickEventHandler>>   m_opPickPostProcessEventHandlers;

        int m_pickPixelTolerance;

        bool m_IsMoveAllowed;                 //是否允许拖拽element
        bool m_IsPickingHighlightOnlyGraphicsNodeAllowed; //是否允许高亮可见的对象被pick到
        bool m_IsSelectByFaceInteriorEnabled; //是否允许按面被选择

        gcmp::OwnerPtr<IActionModifyBehavior> m_opModifyElementsBehavior;
    };
}
